package client

import (
	"database/sql"
	"encoding/xml"
	"fmt"
	"gin-epg/internal/app/client/utils"
	"gin-epg/internal/app/dao"
	"gin-epg/internal/app/entity"
	"gin-epg/internal/app/model"
	"time"
)

// 频道名称映射
var map51zmt = map[string][]string{
	"CCTV4EUO":  {"CCTV4欧洲"},
	"CCTV4AME":  {"CCTV4美洲"},
	"TLC旅游生活频道": {"TLC旅游生活"},
	"达文西频道":     {"达文西"},
	"CHC家庭电影":   {"CHC家庭影院"},
	"CCTV-娱乐":   {"CCTV娱乐"},
	"CCTV-戏曲":   {"CCTV戏曲"},
	"摄影频道":      {"摄影"},
	"茶频道":       {"茶"},
	"书画频道":      {"书画"},
	"车迷频道":      {"车迷"},
	"珠江频道":      {"珠江"},
	// 更多键值对...
}

// 定义忽略列表
var ignoreList51zmt = map[string]bool{
	"noepg": true,
	// 添加更多需要忽略的频道
}

// 51zmt
func Handle51zmtCron() error {
	dao.Logger.Infof("call task handle51zmtCron")
	db := dao.SqlSession
	source := "51zmt"
	// 获取 XML 数据
	xmlData, err := utils.FetchXML("http://epg.51zmt.top:8000/e.xml.gz")
	if err != nil {
		return fmt.Errorf("failed to fetch XML: %v", err)
	}

	// 解析 XML 数据
	var tv model.TV
	if err := xml.Unmarshal(xmlData, &tv); err != nil {
		return fmt.Errorf("failed to parse XML: %v", err)
	}

	// 构造频道id--频道名的map
	mapChannelIdName := utils.BuildChannelMap(&tv)

	// 按天按频道分组处理节目
	type ProgramKey struct {
		Date    string
		Channel string
	}
	programMap := make(map[ProgramKey][]*entity.EpgProgramCollect)

	for _, programme := range tv.Programmes {
		startDate := utils.FormatToDate(programme.Start)
		stopDate := utils.FormatToDate(programme.Stop)

		date := startDate.Format("2006-01-02")
		start := startDate.Format("15:04")
		stop := stopDate.Format("15:04")
		channel := mapChannelIdName[programme.Channel]
		title := programme.Title

		// 检查频道是否在忽略列表中
		if ignoreList51zmt[channel] {
			dao.Logger.Infof("Ignoring channel: %s", channel)
			continue
		}

		// 检查频道名称是否需要映射
		if mappedChannels, ok := map51zmt[channel]; ok {
			for _, mappedChannel := range mappedChannels {
				dateParsed, _ := time.Parse("2006-01-02", date)
				newEpc := &entity.EpgProgramCollect{
					Channel:    mappedChannel,
					Date:       entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}},
					Start:      start,
					End:        stop,
					Title:      title,
					Source:     source,
					CreateTime: entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}},
				}
				key := ProgramKey{Date: date, Channel: mappedChannel}
				programMap[key] = append(programMap[key], newEpc)
			}
		} else {
			dateParsed, _ := time.Parse("2006-01-02", date)
			newEpc := &entity.EpgProgramCollect{
				Channel:    channel,
				Date:       entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}},
				Start:      start,
				End:        stop,
				Title:      title,
				Source:     source,
				CreateTime: entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}},
			}
			key := ProgramKey{Date: date, Channel: channel}
			programMap[key] = append(programMap[key], newEpc)
		}
	}

	// 遍历每个频道和天，构造三个列表
	for key, programs := range programMap {
		// 获取当前日期范围内的已有节目记录，按频道和日期过滤，并指定source
		var existingRecords []entity.EpgProgramCollect
		dateParsed, _ := time.Parse("2006-01-02", key.Date)
		// 打印当前频道和当前日期
		dao.Logger.Infof("Processing channel %s on date %s", key.Channel, key.Date)
		if err := db.Where(&entity.EpgProgramCollect{Channel: key.Channel, Date: entity.NullDate{sql.NullTime{Time: dateParsed, Valid: true}}, Source: source}).Find(&existingRecords).Error; err != nil {
			return fmt.Errorf("failed to get existing records for %s on %s: %v", key.Channel, key.Date, err)
		}

		existingMap := make(map[string]*entity.EpgProgramCollect)
		for i := range existingRecords {
			existingMap[existingRecords[i].Start] = &existingRecords[i]
		}

		var newPrograms, updatePrograms, deletePrograms []entity.EpgProgramCollect

		for _, program := range programs {
			if existingRecord, ok := existingMap[program.Start]; ok {
				if existingRecord.Title != program.Title || existingRecord.End != program.End {
					existingRecord.Title = program.Title
					existingRecord.End = program.End
					existingRecord.UpdateTime = entity.NullTime{sql.NullTime{Time: time.Now(), Valid: true}}
					updatePrograms = append(updatePrograms, *existingRecord)
				}
				delete(existingMap, program.Start)
			} else {
				newPrograms = append(newPrograms, *program)
			}
		}

		// 处理需要删除的记录
		for _, record := range existingMap {
			deletePrograms = append(deletePrograms, *record)
		}

		// 执行数据库操作
		if len(updatePrograms) > 0 {
			for _, program := range updatePrograms {
				if err := db.Model(&program).Updates(entity.EpgProgramCollect{Title: program.Title, End: program.End, UpdateTime: program.UpdateTime}).Error; err != nil {
					dao.Logger.Errorf("update error: %v", err)
				} else {
					dao.Logger.Debugf("update success: %v", program)
				}
			}
		}

		if len(newPrograms) > 0 {
			for _, program := range newPrograms {
				if err := db.Create(&program).Error; err != nil {
					dao.Logger.Errorf("insert error: %v", err)
				} else {
					dao.Logger.Debugf("insert success: %v", program)
				}
			}
		}

		if len(deletePrograms) > 0 {
			for _, program := range deletePrograms {
				if err := db.Delete(&program).Error; err != nil {
					dao.Logger.Errorf("delete error: %v", err)
				} else {
					dao.Logger.Debugf("delete success: %v", program)
				}
			}
		}
	}

	return nil
}
